package ca.qc.bdeb.info.pp2.tp2.controleur;

import ca.qc.bdeb.info.pp2.tp2.utils.utils;
import ca.qc.bdeb.info.pp2.tp2.application.Facade;
import ca.qc.bdeb.info.pp2.tp2.application.PaysBean;
import ca.qc.bdeb.info.pp2.tp2.application.ProvinceBean;
import ca.qc.bdeb.info.pp2.tp2.application.QuartierBean;
import ca.qc.bdeb.info.pp2.tp2.application.TypeMaisonBean;
import ca.qc.bdeb.info.pp2.tp2.application.VilleBean;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;

public class CommandeRechercherProprietes implements Commande
{
    // Indices pour la recherche de propriétés
    private final int PAYS = 1;
    private final int PROVINCE = 2;
    private final int VILLE = 3;
    private final int QUARTIER = 4;
    private final int CODE_POSTAL = 5;
    private String next;
    private String selectionListePays = null;
    private String selectionListeProvinces = null;
    private String[] selectionListeVilles = null;
    private String selectionListeQuartiers = null;
    private String selectionListeCodePostaux = null;
    private String selectionListeTypeMaisons = null;

    public CommandeRechercherProprietes(String next)
    {
        this.next = next.toLowerCase();
    }

    @Override
    public String executer(HttpServletRequest req) throws CommandeException
    {
        Facade f = new Facade();
        // Indice pour la recherche de propriétés
        int changement = PAYS;
        /*
         * Est-ce que le programme doit modifier une liste de sélection
         * automatiquement?
         */
        Boolean faireChangementAutomatique = false;

        /*
         * La premiere fois, l'utilisateur n'a pas choisis de liste, donc le
         * programme doit les modifier tous, donc il met que l'utilisateur a
         * choisis la liste de pays pour etre en mesure de changer tous les
         * champs
         */
        if (req.getParameter(ConstantesWeb.LISTE_PAYS) != null)
            changement = determinerChangement(req);

        //Placer le code de cette section dans la commande appropriée
        selectionListePays = req.getParameter(ConstantesWeb.LISTE_PAYS);
        selectionListeProvinces = req.getParameter(ConstantesWeb.LISTE_PROVINCES);
        selectionListeVilles = req.getParameterValues(ConstantesWeb.LISTE_VILLES);
        selectionListeQuartiers = req.getParameter(ConstantesWeb.LISTE_QUARTIERS);
        selectionListeCodePostaux = req.getParameter(ConstantesWeb.LISTE_CODE_POSTAUX);
        selectionListeTypeMaisons = req.getParameter(ConstantesWeb.LISTE_TYPE_MAISONS);



        if (!faireChangementAutomatique)
            faireChangementAutomatique = verifierAChanger(changement, PAYS);
        getPays(req, f);

        if (!faireChangementAutomatique)
            faireChangementAutomatique = verifierAChanger(changement, PROVINCE);
        getProvinces(req, f, faireChangementAutomatique);

        if (!faireChangementAutomatique)
            faireChangementAutomatique = verifierAChanger(changement, VILLE);
        getVilles(req, f, faireChangementAutomatique);

        if (!faireChangementAutomatique)
            faireChangementAutomatique = verifierAChanger(changement, QUARTIER);
        getQuartiers(req, f, faireChangementAutomatique);

//        if (!faireChangementAutomatique)
//            faireChangementAutomatique = 
//                    verifierAChanger(changement, CODE_POSTAL);
//        getCodePostaux(req, f, faireChangementAutomatique);

        getTypeMaisons(req, f);

        getChampSpecifique(req, ConstantesWeb.VALEUR_PRIX_BAS);
        getChampSpecifique(req, ConstantesWeb.VALEUR_PRIX_HAUT);
        getChampSpecifique(req, ConstantesWeb.VALEUR_NOMBRE_CHAMBRES);
        getChampSpecifique(req, ConstantesWeb.VALEUR_NOMBRE_SALLES_BAINS);
        getChampSpecifique(req, ConstantesWeb.VALEUR_NOMBRE_ETAGES);
        getChampSpecifique(req, ConstantesWeb.VALEUR_NOMBRE_PIECE);
        getChampSpecifique(req, ConstantesWeb.VALEUR_ANNEE_CONSTRUCTION);

        getRadioSpecifique(req, ConstantesWeb.VALEUR_PISCINE);
        getRadioSpecifique(req, ConstantesWeb.VALEUR_STATIONNEMENT);
        getRadioSpecifique(req, ConstantesWeb.VALEUR_SOUS_SOL);
        getRadioSpecifique(req, ConstantesWeb.VALEUR_GARAGE);
        
        getCheckboxSpecifique(req, ConstantesWeb.VALEUR_PRIX_ORDRE);

        return next;
    }

    /**
     * Cette fonction determine c'est quelle liste de recherche que 
     * l'utilisateur désire modifier.
     * @param req : la requête
     * @return changement
     */
    private int determinerChangement(HttpServletRequest req)
    {
        int changement = -1;
        // La valeur précédente d'une liste spécifique
        String selectionPrecedante = "";
        // La valeur courante de la même liste spécifique
        String selection = "";
        // Est-ce que la sélection de cette même liste à été modifiée?
        Boolean changementTrouver = false;

        // Cette boucle parcours toutes les listes
        for (int i = PAYS; i <= CODE_POSTAL && !changementTrouver; i++) {
            selectionPrecedante = trouverSelectionPrecedante(i);
            selection = trouverListe(i);

            // req.getParameter(selection) : détermine la sélection courante 
            changementTrouver = verifierSelection(selectionPrecedante, req.getParameter(selection));

            /*
             * Si la liste qui a été modifiée par l'utilisateur est trouvé,
             * changement contient maintenant l'indice pour la recherche de 
             * propriétés
             */
            if (changementTrouver) {
                changement = i;
                changementTrouver = true;
            }
        }
        return changement;
    }

    /**
     * Cette méthode trouve qu'est ce qui était la sélection précédante pour une
     * liste spécifique.
     * @param indiceListe : indice pour la recherche de propriétés
     * @return selectionPrecedante
     */
    private String trouverSelectionPrecedante(int indiceListe)
    {
        String selectionPrecedante = "";
        String selectionVillesPrecedantes[];

        switch (indiceListe) {
            case PAYS:
                selectionPrecedante = selectionListePays;
                break;
            case PROVINCE:
                selectionPrecedante = selectionListeProvinces;
                break;
            case VILLE:
                selectionVillesPrecedantes = selectionListeVilles;
                break;
            case QUARTIER:
                selectionPrecedante = selectionListeQuartiers;
                break;
            case CODE_POSTAL:
                selectionPrecedante = selectionListeCodePostaux;
        }
        return selectionPrecedante;
    }

    /**
     * Cette méthode trouve la liste courante pour que le programme puisse plus
     * tard déterminer la sélection courante.
     * @param indiceListe : indice pour la recherche de propriétés
     * @return selection
     */
    private String trouverListe(int indiceListe)
    {
        String selection = "";

        switch (indiceListe) {
            case PAYS:
                selection = ConstantesWeb.LISTE_PAYS;
                break;
            case PROVINCE:
                selection = ConstantesWeb.LISTE_PROVINCES;
                break;
            case VILLE:
                selection = ConstantesWeb.LISTE_VILLES;
                break;
            case QUARTIER:
                selection = ConstantesWeb.LISTE_QUARTIERS;
                break;
            case CODE_POSTAL:
                selection = ConstantesWeb.LISTE_CODE_POSTAUX;
        }
        return selection;
    }

    /**
     * Cette méthode détermine si une liste spécifique est la liste que
     * l'utilisateur a choisi de modifier.
     * @param selectionPrecedante : la sélection précédante pour une liste 
     * spécifique
     * @param selectionCourante : la sélection courant pour une liste 
     * spécifique
     * @return true ou false
     */
    private boolean verifierSelection(String selectionPrecedante, String selectionCourante)
    {
        /*
         * Si selectionCourante == null, c'est parce que le programme entre dans
         * la page de recherche pour la première fois. Si 
         * selectionPrecedante.equals(selectionCourante), c'est parce qu'il n'y
         * a pas eu de changement.
         */
        if (selectionCourante == null
                || selectionPrecedante.equals(selectionCourante))
            return false;
        else
            return true;
    }

    /**
     * Cette méthode détermine si la liste doit être changée de façon
     * automatique.
     * @param changement : indice pour la recherche de propriétés
     * @param indiceImplantationCourant : indice de la prochaine liste à se
     * faire implanter
     * @return aChanger
     */
    private boolean verifierAChanger(int changement, int indiceImplantationCourant)
    {
        Boolean aChanger = false;

        /*
         * Ici, c'est changement + 1 puisque la liste que l'utilisateur à
         * choisis ne doit pas être modifier. C'est à partier de la prochaine
         * liste, que les modification doivent commencées.
         */
        switch (indiceImplantationCourant) {
            case PAYS:
                aChanger = changement + 1 == PAYS;
                break;
            case PROVINCE:
                aChanger = changement + 1 == PROVINCE;
                break;
            case VILLE:
                aChanger = changement + 1 == VILLE;
                break;
            case QUARTIER:
                aChanger = changement + 1 == QUARTIER;
                break;
            case CODE_POSTAL:
                aChanger = changement + 1 == CODE_POSTAL;
        }
        return aChanger;
    }

    /**
     * Cette méthode cherche la liste de pays.
     * @param req : la requête
     * @param f : la façade
     */
    private void getPays(HttpServletRequest req, Facade f)
    {
        String id = "";
        String nom = "";

        TreeMap<String, String> valeursListePays = new TreeMap<String, String>();

        List<PaysBean> pays = new ArrayList<PaysBean>();

        pays = f.getPays();

        if (selectionListePays == null)
            selectionListePays = "1";

        for (int i = 0; i < pays.size(); i++) {
            id = "" + pays.get(i).getId();
            nom = pays.get(i).getPays();

            valeursListePays.put(id, nom);
        }
        //valeursListePays.put("10", "test");

        req.setAttribute(ConstantesWeb.VALEURS_LISTE_PAYS, valeursListePays);
        req.setAttribute(ConstantesWeb.SELECTION_LISTE_PAYS, selectionListePays);
    }

    /**
     * Cette méthode cherche la liste de provinces.
     * @param req : la requête
     * @param f : la façade
     */
    private void getProvinces(HttpServletRequest req, Facade f, Boolean faireChangementAutomatique)
    {

        String idPays = selectionListePays;
        String idProvince = "";
        String nom = "";

        TreeMap<String, String> valeursListeProvinces = new TreeMap<String, String>();

        List<ProvinceBean> province = new ArrayList<ProvinceBean>();

        if (!utils.isDigit(idPays))
            idPays = "1";

        province = f.getProvince(Integer.parseInt(idPays));

        if (province == null || !province.isEmpty())
            for (ProvinceBean p : province) {
                idProvince = "" + p.getId();
                nom = p.getProvince();

                valeursListeProvinces.put(idProvince, nom);
            }
        else {
            idPays = "1";
            province = f.getProvince(Integer.parseInt(idPays));
            if (province != null)
                for (ProvinceBean p : province) {
                    idProvince = "" + p.getId();
                    nom = p.getProvince();

                    valeursListeProvinces.put(idProvince, nom);
                }
        }

        if (faireChangementAutomatique)
            selectionListeProvinces = "11";
        else
            selectionListeProvinces = req.getParameter(ConstantesWeb.LISTE_PROVINCES);

        req.setAttribute(ConstantesWeb.VALEURS_LISTE_PROVINCES, valeursListeProvinces);
        req.setAttribute(ConstantesWeb.SELECTION_LISTE_PROVINCES, selectionListeProvinces);
    }

    /**
     * Cette méthode cherche la liste de villes.
     * @param req : la requête
     * @param f : la façade
     */
    private void getVilles(HttpServletRequest req, Facade f, Boolean faireChangementAutomatique)
    {
        String idProvince = selectionListeProvinces;
        String idVille = "";
        String nom = "";

        TreeMap<String, String> valeursListeVilles = new TreeMap<String, String>();

        List<VilleBean> ville = new ArrayList<VilleBean>();

        ville = f.getVille(Integer.parseInt(idProvince));

        if (ville == null || !ville.isEmpty())
            for (VilleBean v : ville) {
                idVille = "" + v.getId();
                nom = v.getVille();

                valeursListeVilles.put(idVille, nom);
            }

        if (faireChangementAutomatique) {
            selectionListeVilles = new String[1];
            selectionListeVilles[0] = valeursListeVilles.firstKey();
        } else
            selectionListeVilles = req.getParameterValues(ConstantesWeb.LISTE_VILLES);

        req.setAttribute(ConstantesWeb.VALEURS_LISTE_VILLES, valeursListeVilles);
        req.setAttribute(ConstantesWeb.SELECTION_LISTE_VILLES, selectionListeVilles);
    }

    /**
     * Cette méthode cherche la liste de quartiers.
     * @param req : la requête
     * @param f : la façade
     */
    private void getQuartiers(HttpServletRequest req, Facade f, Boolean faireChangementAutomatique)
    {
        String[] idsVilles = selectionListeVilles;
        String idQuartier = "";
        String nom = "";

        TreeMap<String, String> valeursListeQuartiers = new TreeMap<String, String>();

        List<QuartierBean> quartier = new ArrayList<QuartierBean>();

        if (selectionListeVilles != null)
            quartier = f.getQuartier(idsVilles);

        if (quartier == null || !quartier.isEmpty())
            for (QuartierBean q : quartier) {
                idQuartier = "" + q.getId();
                nom = q.getQuartier() + ", " + f.getNomVille(q.getIdVille());

                valeursListeQuartiers.put(idQuartier, nom);
            }

        if (faireChangementAutomatique)
            selectionListeQuartiers = valeursListeQuartiers.firstKey();
        else
            selectionListeQuartiers = req.getParameter(ConstantesWeb.LISTE_QUARTIERS);

        req.setAttribute(ConstantesWeb.VALEURS_LISTE_QUARTIERS, valeursListeQuartiers);
        req.setAttribute(ConstantesWeb.SELECTION_LISTE_QUARTIERS, selectionListeQuartiers);
    }

    private void getTypeMaisons(HttpServletRequest req, Facade f)
    {
        String id = selectionListeTypeMaisons;
        String description = "";

        TreeMap<String, String> valeursListeTypeMaisons = new TreeMap<String, String>();

        List<TypeMaisonBean> typeMaison = new ArrayList<TypeMaisonBean>();

        typeMaison = f.getTypeMaison();

        if (typeMaison == null || !typeMaison.isEmpty()) {
            for (TypeMaisonBean tm : typeMaison) {
                id = "" + tm.getId();
                description = tm.getDescription();

                valeursListeTypeMaisons.put(id, description);
            }
            selectionListeTypeMaisons = req.getParameter(ConstantesWeb.LISTE_TYPE_MAISONS);
        }

        req.setAttribute(ConstantesWeb.VALEURS_LISTE_TYPE_MAISONS, valeursListeTypeMaisons);
        req.setAttribute(ConstantesWeb.SELECTION_LISTE_TYPE_MAISONS, selectionListeTypeMaisons);
    }

    /**
     * Cette méthode cherche un champ spécifique
     * @param req : la requête
     * @param nomChamp : le nom d'un champ
     */
    private void getChampSpecifique(HttpServletRequest req, String nomChamp)
    {
        String valeurTemp;

        valeurTemp = req.getParameter(nomChamp);
        valeurTemp = (valeurTemp != null) ? valeurTemp : "";
        req.setAttribute(nomChamp, valeurTemp);
    }

    private void getRadioSpecifique(HttpServletRequest req, String nomChamp)
    {
        String valeurTemp;

        valeurTemp = req.getParameter(nomChamp);
        valeurTemp = (valeurTemp != null) ? valeurTemp : ConstantesWeb.SELECTION_RADIO_INDIFFERENT;
        req.setAttribute(nomChamp, valeurTemp);
    }
    
    private void getCheckboxSpecifique(HttpServletRequest req, String nomChamp)
    {
        String valeurTemp;

        valeurTemp = req.getParameter(nomChamp);
        valeurTemp = (valeurTemp == null) ? ConstantesWeb.SELECTION_CHECKBOX_OFF 
                : ConstantesWeb.SELECTION_CHECKBOX_ON;
        req.setAttribute(nomChamp, valeurTemp);
    }
}
